class Snake {
  // 蛇容器
  snake: HTMLElement;
  // 蛇头 
  head: HTMLElement;
  // 蛇体
  bodies: HTMLCollectionOf<HTMLDivElement>;
  constructor() {
    this.snake = document.getElementById('snake')!;
    this.head = document.querySelector('#snake > div')!;
    this.bodies = this.snake.getElementsByTagName('div');
  }
  // 获取蛇头坐标
  get headX(): number {
    return this.head.offsetLeft;
  }
  get headY(): number {
    return this.head.offsetTop;
  }
  // 蛇体及蛇头X移动 
  set X(value: number) {
    if(value < 0 || value > 290) {
      throw new Error('蛇撞墙了');
    }
    // 发生掉头
    if(this.bodies[1] && this.bodies[1].offsetLeft === value) {
      if(value > this.headX) {
        // 蛇掉头往右走 应该继续往左走
        value = this.headX - 10
      } else {
        // 蛇掉头往左走 应该继续往右走
        value = this.headX + 10
      }
    }
    // 先移动蛇体 再移动蛇头
    this.moveBody();
    this.head.style.left = value + 'px';
    this.checkHeadBody();
  }
  // 蛇体及蛇头Y移动
  set Y(value: number) {
    if(value < 0 || value > 290) {
      throw new Error('蛇撞墙了');
    }
    if(this.bodies[1] && this.bodies[1].offsetTop === value) {
      if(value > this.headY) {
        value = this.headY - 10
      } else {
        value = this.headY + 10
      }
    }
    this.moveBody();
    this.head.style.top = value + 'px';
    this.checkHeadBody();
  }
  // 添加一个蛇体
  addBody(): void {
    this.snake.insertAdjacentHTML('beforeend', '<div></div>');
  }
  // 蛇体移动 后一节蛇体位置等于前一节蛇体位置
  moveBody(): void {
    for (let i = this.bodies.length - 1; i > 0; i--) {
      this.bodies[i].style.left = this.bodies[i - 1].offsetLeft + 'px';
      this.bodies[i].style.top = this.bodies[i - 1].offsetTop + 'px';
    }
  }
  // 检查头和蛇体是否相撞
  checkHeadBody(): void {
    for(let i = 1; i < this.bodies.length; i++) {
      let body = this.bodies[i];
      if(body.offsetLeft === this.headX && body.offsetTop === this.headY) {
        throw new Error('蛇头蛇体相撞了');
      }
    }
  }
}

export default Snake;